package org.zoomdev.zoom;

import com.alibaba.fastjson2.JSONWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.zoomdev.zoom.asm.ClassBuilder;
import org.zoomdev.zoom.security.Sensitive;

public class UserWriterGenerator {

    public static byte[] generateUserWriterClass() throws ClassNotFoundException {
        String className = "org/zoomdev/zoom/GeneratedUserWriter";
        String userDescriptor = Type.getDescriptor(User.class);
        String signature = "Ljava/lang/Object;Lorg/zoomdev/zoom/BeanWriter<" + userDescriptor + ">;";

        return new ClassBuilder(className)
                .extend(Object.class)
                .implement(BeanWriter.class)
                .withSignature(signature)


                // 添加字段
                .addField("sensitives", Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, Sensitive[].class)

                // 构造函数
                .createConstructor(method -> method
                        .params(Sensitive[].class)
                        .invokeConstructor()
                        .loadThis().loadArg(0).putField("sensitives")
                        .returnValue())

                .createMethod("write", method -> {
                    method.withAccess(Opcodes.ACC_PUBLIC)
                            .params(JSONWriter.class, Object.class)
                            .returns(void.class)

                            // 定义标签

//                            // 将Object转为User
                            // 类型转换并存储
                            .loadArg(1)
                            .checkcast(User.class)
                            .storeLocal("user", User.class)


//                            // 开始对象
                            .call(0, "startObject", void.class)

                            // 序列化 name 字段
                            .loadArg(0)
                            .push("name")
                            .invokeVirtual(JSONWriter.class, "writeRaw", void.class, String.class)


                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeColon", void.class)
                            .loadArg(0)  // 加载 JSONWriter 用于后续调用            //writer
                            .loadThis()
                            .getField("sensitives", Sensitive[].class)
                            .push(0)
                            .arrayLoad(Sensitive.class)         //Sensitive se = this.sensitives[0]
                            .loadLocal("user")
                            .invokeVirtual(User.class, "getName", String.class)     //user.getName()
                            .invokeInterface(Sensitive.class, "toSensitiveString", String.class, Object.class)      //se.toSensitiveString(str)
                            .invokeVirtual(JSONWriter.class, "writeString", void.class, String.class)           // writer
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeComma", void.class)


                            // 序列化 adult 字段
                            .loadArg(0)
                            .push("adult")
                            .invokeVirtual(JSONWriter.class, "writeRaw", void.class, String.class)
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeColon", void.class)
                            .loadArg(0)  // 加载 JSONWriter 用于后续调用
                            .loadLocal("user")
                            .invokeVirtual(User.class, "isAdult", boolean.class)
                            .invokeVirtual(JSONWriter.class, "writeBool", void.class, boolean.class)
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeComma", void.class)

                            // 序列化 idCard 字段
                            .loadArg(0)
                            .push("idCard")
                            .invokeVirtual(JSONWriter.class, "writeRaw", void.class, String.class)
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeColon", void.class)
                            .loadArg(0)  // 加载 JSONWriter 用于后续调用
                            .loadThis()
                            .getField("sensitives", Sensitive[].class)
                            .push(1)
                            .arrayLoad(Sensitive.class)
                            .loadLocal("user")
                            .invokeVirtual(User.class, "getIdCard", String.class)
                            .invokeInterface(Sensitive.class, "toSensitiveString", String.class, Object.class)
                            .invokeVirtual(JSONWriter.class, "writeString", void.class, String.class)
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeComma", void.class)

                            // 序列化 bankCard 字段
                            .loadArg(0)
                            .push("bankCard")
                            .invokeVirtual(JSONWriter.class, "writeRaw", void.class, String.class)
                            .loadArg(0)
                            .invokeVirtual(JSONWriter.class, "writeColon", void.class)
                            .loadArg(0)  // 加载 JSONWriter 用于后续调用
                            .loadThis()
                            .getField("sensitives", Sensitive[].class)
                            .push(2)
                            .arrayLoad(Sensitive.class)
                            .loadLocal("user")
                            .invokeVirtual(User.class, "getBankCard", String.class)
                            .invokeInterface(Sensitive.class, "toSensitiveString", String.class, Object.class)
                            .invokeVirtual(JSONWriter.class, "writeString", void.class, String.class)

//                            // 结束对象
                            .call(0, "endObject", void.class)


                            .returnValue()
                    ;
                })

                .build();

    }


}